using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Threading;

using System.Security.Cryptography.X509Certificates;
using System.Xml;

using Microsoft.Web.Services3;
using Microsoft.Web.Services3.Design;
using Microsoft.Web.Services3.Security;
using Microsoft.Web.Services3.Security.Tokens;

using EC2Manage.com.amazonaws.s3;

namespace EC2Manage
{
    /// <summary>
    /// This Class supports all the AmazonAWS calls in library form with standardized datatypes
    /// Any changes to the WSDL may require refactoring of the library
    /// </summary>
    public class AWSLibrary
    {
        public AmazonEC2Wse ec2;
        private ServicePolicy sp;
        //public static string CERT_FILE = @"C:\vs2005code\AmazonAWSLib\AWSCertificate.p12";
        public static string CERT_FILE;

        public AWSLibrary(string publicKey)
        {
            if (publicKey == null) { return; }
            CERT_FILE = publicKey;

            ec2 = new AmazonEC2Wse();
            sp = new ServicePolicy();
            ec2.SetPolicy(sp);

        }



        /// <summary>
        /// This method was used to test loading a cert from the store and from a p12 file
        /// </summary>
        public void CertWork()
        {
            X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            store.Open(OpenFlags.ReadOnly);
            try
            {
                X509Certificate2Collection Results = store.Certificates.Find(X509FindType.FindBySubjectName, "51xh7n5ppwvf", false);
                X509Certificate2 cert = Results[0];
                X509ContentType xCon = X509Certificate2.GetCertContentType(CERT_FILE);

                //Note: Using OpenSSL to gen the cert file, you MUST use the "" for the password! Quirky...
                X509Certificate2 c = new X509Certificate2(CERT_FILE, "");
            }
            catch { }
        }

        /// <summary>
        /// This class extends Policy so that Web Services/SOAP policy can be programmatically set instead
        /// of through a policy XML file
        /// </summary>
        public class ServicePolicy : Policy
        {

            public ServicePolicy()
                : base()
            {
                // Create a new instance of the MutualCertificate11 turnkey security assertion.
                //MutualCertificate11Assertion assertion = new MutualCertificate11Assertion();
                // Specify a security token provider for the Web service's security credentials.
                //assertion.ServiceX509TokenProvider = new X509TokenProvider(StoreLocation.LocalMachine, StoreName.My, "CN=WSE2QuickStartServer");

                //MutualCertificate10Assertion assertion = new MutualCertificate10Assertion();
                AWSMutualCertificate10Assertion assertion = new AWSMutualCertificate10Assertion();

                assertion.EstablishSecurityContext = false;
                assertion.RenewExpiredSecurityContext = true;
                assertion.RequireSignatureConfirmation = false;
                assertion.MessageProtectionOrder = MessageProtectionOrder.SignBeforeEncrypt;
                assertion.RequireDerivedKeys = false;
                assertion.TtlInSeconds = 300;


                //These grab the Cert from the store (has to have been imported)
                //assertion.ServiceX509TokenProvider = new X509TokenProvider(StoreLocation.CurrentUser, StoreName.My, "51xh7n5ppwvf", X509FindType.FindBySubjectName);
                //assertion.ClientX509TokenProvider = new X509TokenProvider(StoreLocation.CurrentUser, StoreName.My, "51xh7n5ppwvf", X509FindType.FindBySubjectName);

                //This version uses a custom Provider to merely supply the cert we specified
                assertion.ServiceX509TokenProvider = new JDX509TokenProvider();
                assertion.ClientX509TokenProvider = new JDX509TokenProvider();

                //X509TokenProvider x5 = new X509TokenProvider(StoreLocation.CurrentUser, StoreName.My, "51xh7n5ppwvf", X509FindType.FindBySubjectName);
                //X509SecurityToken st = x5.GetToken();

                assertion.Protection.Request.SignatureOptions = 0;
                assertion.Protection.Request.SignatureOptions |= SignatureOptions.IncludeAddressing;
                assertion.Protection.Request.SignatureOptions |= SignatureOptions.IncludeTimestamp;
                assertion.Protection.Request.SignatureOptions |= SignatureOptions.IncludeSoapBody;

                assertion.Protection.Request.EncryptBody = false;

                // Add the policy assertion to the policy.
                this.Assertions.Add(assertion);
            }

        }

        /// <summary>
        /// Used to override the default provider which supplies the cert from the MS Cert Store
        /// We, instead, want to specify a p12 file to load the cert and use to SOAP sign
        /// </summary>
        public class JDX509TokenProvider : X509TokenProvider
        {
            public string X509Certificate;

            public override X509SecurityToken GetToken()
            {
                //return new X509SecurityToken(new X509Certificate2(@"C:\Drops\OpenSSL\bin\Amazon.p12", ""));
                return new X509SecurityToken(new X509Certificate2(CERT_FILE, ""));
            }
        }

        /// <summary>
        /// This class is a simple override for the SOAPFilter
        /// </summary>
        class AWSMutualCertificate10Assertion : MutualCertificate10Assertion
        {
            public override SoapFilter CreateClientInputFilter(FilterCreationContext context)
            {
                return null;
            }
        }

    }
}
